<!--
Copyright 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">

<polymer-element name="ct-test-list" attributes="tests">
  <template>
    <style>
      :host {
        display: block;
      }

      :host > div {
        /* Be at least the height of a paper-icon-button.
           So things line up nicely. */
        min-height: 24px;
      }

      .test-failures {
        margin-left: 15px;
      }

      paper-icon-button {
        vertical-align: middle;
      }

      paper-icon-button::shadow #icon {
        margin: 0;
      }
    </style>
    <template repeat="{{ groups in testGroups_ }}">
      <template if="{{ groups.tests.length }}">
        <div><span style="font-weight: bold">Step:</span> {{ groups.step }}</div>
      </template>

      <template repeat="{{ group in groups.tests | maybeTruncate(groups.expanded) }}">
        <!-- Case 1: single test failure -->
        <template if="{{ group.name && (group.tests.length == 1 || group.expanded) }}">
          <template repeat="{{ test in group.tests }}">
            <div class="test-failures">
              <a href="{{ test | flakinessDashboardURL }}">{{ test.testName }}</a>
            </div>
          </template>
        </template>
        <!-- Case 2: group of tests failed -->
        <template if="{{ group.name && group.tests.length > 1 && !group.expanded }}">
          <div class="test-failures">
            {{ group.name }} ({{ group.tests.length }} Tests)
            <paper-icon-button id="expand" icon="unfold-more" step="{{ groups.step }}" group="{{ group.name }}" on-click="{{ _innerExpand }}"></paper-icon-button>
          </div>
        </template>
      </template>
      <template if="{{ !groups.expanded }}">
        <div class="test-failures">
          {{ groups.tests.length - kMaxTestsPerStep }} more
          <paper-icon-button id="outerExpand" icon="unfold-more" step="{{ groups.step }}" on-click="{{ _outerExpand }}"></paper-icon-button>
        </div>
      </template>
    </template>
  </template>
  <script>
    Polymer('ct-test-list', {
      kMaxTestsPerStep: 10,

      testsChanged: function() {
        var groups = {};
        if (this.tests) {
          this.tests.forEach(function(test) {
            if (!groups[test.step])
              groups[test.step] = {};
            var testName = test.reasonGroupName();
            if (!groups[test.step][testName])
              groups[test.step][testName] = [];
            groups[test.step][testName].push(test);
          }.bind(this));
        }
        this.testGroups_ = [];
        Object.keys(groups, function(step, testsByName) {
          var tests = [];
          Object.keys(testsByName, function(name, testList) {
            if (name == 'undefined')
              name = undefined;
            tests.push({'name': name, 'tests': testList, 'expanded': false});
          }.bind(this));
          tests.sortBy('name');
          // The + 1 is to make sure at least 2 tests are hidden by the message.
          this.testGroups_.push({'step': step, 'tests': tests, 'expanded': tests.length <= (this.kMaxTestsPerStep + 1)});
        }.bind(this));
        this.testGroups_.sortBy('step');
      },

      _innerExpand: function(evt) {
        step = evt.target.attributes['step'].value;
        name = evt.target.attributes['group'].value;
        this.testGroups_.forEach(function(testGroup) {
          if (testGroup.step == step) {
            testGroup.tests.forEach(function(test) {
              // FIXME: This attribute should be persisted over reloads.
              if (test.name == name)
                test.expanded = true;
            });
          }
        });
      },

      _outerExpand: function(evt) {
        var step = evt.target.attributes['step'].value;
        this.testGroups_.forEach(function(testGroup) {
          if (testGroup.step == step) {
            testGroup.expanded = true;
          }
        });
      },

      flakinessDashboardURL: function(test) {
        return test.flakinessDashboardURL();
      },

      // FIXME: Remove maybeTruncate. Persist the expanded list as described in
      // http://crbug.com/417159.
      maybeTruncate: function(input, expanded) {
        if (expanded)
          return input;
        return input.slice(0, this.kMaxTestsPerStep);
      },
    });
  </script>
</polymer-element>
